/**
 * @开发版权 
 * @项目名称 轻量数据中台(LDMP)
 * @版本信息 v1.0
 * @开发人员 zhous
 * @开发日期 2025-01-17
 * @修订日期
 * @描述  DbapiController
 */
package com.microframework.boot.customapi.controller;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson2.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.microframework.base.core.datasource.annotation.Tx;
import com.microframework.base.core.util.SecurityUtils;
import com.microframework.base.core.util.UuidUtil;
import com.microframework.base.web.resp.R;
import com.microframework.boot.customapi.model.domain.Dbapi;
import com.microframework.boot.customapi.model.domain.DbapiGroup;
import com.microframework.boot.customapi.model.domain.DbapiReqArguments;
import com.microframework.boot.customapi.model.domain.DbapiSql;
import com.microframework.boot.customapi.model.domain.Sql;
import com.microframework.boot.customapi.model.dto.DbapiArgument;
import com.microframework.boot.customapi.service.IDbapiService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Tag(name = "dbapi管理")
@RequiredArgsConstructor
@RestController
@RequestMapping("/custom-api/db")
@Slf4j
public class DbapiController{

	@Autowired
	private IDbapiService dbapiService;

	@Operation(summary = "获取Dbapi 分组列表")
	@Parameters({ @Parameter(name = "name", description = "组名", required = false) })
	@GetMapping(value = { "/group/list" }, produces = "application/json; charset=utf-8")
	public R<List<DbapiGroup>> getDbapiGroups(HttpServletRequest request,
			@RequestParam(name = "name", required = false, defaultValue = "") String name) throws Exception {
		String sqlExceptSelect = " from " + DbapiGroup.TABLE_NAME + "  a WHERE 1=1 ";

		if (!StrKit.isBlank(name)) {
			sqlExceptSelect += " and a.name like '%" + name + "%' ";
		}
		sqlExceptSelect += "  ORDER BY a.sort asc ";
		return R.ok(DbapiGroup.dao.find("select a.* " + sqlExceptSelect));
	}

	@Operation(summary = "保存Dbapi分组")
	@Parameters({ @Parameter(name = "group", description = "Dbapi 分组对象", required = true) })
	@Tx(value="")
	@RequestMapping(value = "/group/save", method = RequestMethod.POST)
	public R<DbapiGroup> saveDbapiGroup(HttpServletRequest request, @RequestBody DbapiGroup group) {
		try {
			if (StrKit.notBlank(group.getId())) {
				group.setUpdateUserId(SecurityUtils.getUserId());
				group.setUpdateTime(new Date(System.currentTimeMillis()));
				if (group.update()) {
					return R.ok(group);
				} else {
					return R.fail("更新失败！");
				}
			} else {
				group.setId(UuidUtil.getUUID());
				group.setCreateUserId(SecurityUtils.getUserId());
				group.setCreateTime(new Date(System.currentTimeMillis()));
				if (group.save()) {
					return R.ok(group);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}

	@Operation(summary = "删除Dbapi 分组对象")
	@Parameters({ @Parameter(name = "id", description = "Dbapi 分组对象 id", required = true) })
	@DeleteMapping("/group/{id}")
	@Tx(value="micro_dbapi")
	public R<String> deleteDbapiGroupByIds(@PathVariable("id") String id) {
		dbapiService.deleteGroupByIds(id);
		return R.ok();
	}

	@Operation(summary = "分页获取Dbapi列表")
	@Parameters({ @Parameter(name = "keywords", description = "关键字", required = false),
			@Parameter(name = "cur", description = "当前页码", required = true),
			@Parameter(name = "limit", description = "每页数据量", required = true) })
	@GetMapping(value = { "/pages" }, produces = "application/json; charset=utf-8")
	public R<Page<Dbapi>> pages(HttpServletRequest request,
			@RequestParam(name = "keywords", required = false, defaultValue = "") String keywords,
			@RequestParam(name = "cur", required = false, defaultValue = "1") int cur,
			@RequestParam(name = "limit", required = false, defaultValue = "10") int limit) throws Exception {
		String sqlExceptSelect = " from " + Dbapi.TABLE_NAME + "  a WHERE 1=1 ";
		if (!StrKit.isBlank(keywords)) {
			sqlExceptSelect += " and (a.name like '%" + keywords + "%' or a.code like '%" + keywords + "%') ";
		}
		sqlExceptSelect += "  ORDER BY a.sort asc ";
		return R.ok(Dbapi.dao.paginate(cur, limit, "select a.* ", sqlExceptSelect));
	}

	@Operation(summary = "保存Dbapi对象")
	@Parameters({ @Parameter(name = "dbapi", description = "Dbapi 对象", required = true) })
	@Tx
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public R<Dbapi> save(HttpServletRequest request, @RequestBody Dbapi dbapi) {
		try {
			if (StrKit.notBlank(dbapi.getId())) {
				
				Dbapi checkDbapi1=Dbapi.dao.findFirst("select * from "+Dbapi.TABLE_NAME+" where id!=? and code=? ",dbapi.getId(),dbapi.getCode());
				if(checkDbapi1!=null) {
					return R.fail("接口标识已存在！");
				}
				
				Dbapi checkDbapi2=Dbapi.dao.findFirst("select * from "+Dbapi.TABLE_NAME+" where id!=? and uri=? ",dbapi.getId(),dbapi.getUri());
				if(checkDbapi2!=null) {
					return R.fail("接口请求地址已存在！");
				}
				dbapi.setUpdateUserId(SecurityUtils.getUserId());
				dbapi.setUpdateTime(new Date(System.currentTimeMillis()));
				if (dbapi.update()) {
					return R.ok(dbapi);
				} else {
					return R.fail("更新失败！");
				}
			} else {
				
				Dbapi checkDbapi1=Dbapi.dao.findFirst("select * from "+Dbapi.TABLE_NAME+" where code=? ",dbapi.getCode());
				if(checkDbapi1!=null) {
					return R.fail("接口标识已存在！");
				}
				
				Dbapi checkDbapi2=Dbapi.dao.findFirst("select * from "+Dbapi.TABLE_NAME+" where uri=? ",dbapi.getUri());
				if(checkDbapi2!=null) {
					return R.fail("接口请求地址已存在！");
				}
				
				dbapi.setId(UuidUtil.getUUID());
				dbapi.setCreateUserId(SecurityUtils.getUserId());
				dbapi.setCreateTime(new Date(System.currentTimeMillis()));
				if (dbapi.save()) {
					return R.ok(dbapi);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}

	@Operation(summary = "删除Dbapi")
	@Parameters({ @Parameter(name = "ids", description = "Dbapi id 集合(逗号分隔字符串)", required = true) })
	@DeleteMapping("/{ids}")
	@Tx(value="micro_dbapi")
	public R<String> delete(@PathVariable("ids") String ids) {
		String[] arr=ids.split(",");
		if(ids==null || ids.length()<=0) {
			return R.fail("请选择需要删除的接口.");
		}
		for(String id:arr) {
			Db.use(DbapiReqArguments.DS_NAME).delete("delete from " + DbapiReqArguments.TABLE_NAME + " where api_id=? ", id);
			Db.use(DbapiSql.DS_NAME).delete("delete from " + DbapiSql.TABLE_NAME + " where api_id=? ", id);
			Db.use(Dbapi.DS_NAME).delete("delete from " + Dbapi.TABLE_NAME + " where id=?", id);
		}
		return R.ok();
	}

	@Operation(summary = "获取Dbapi 请求参数列表")
	@Parameters({ @Parameter(name = "apiId", description = "DbapiSql对象 Id", required = false) })
	@GetMapping(value = { "/req_arguments/list" }, produces = "application/json; charset=utf-8")
	public R<List<DbapiArgument>> getDbapiReqArguments(HttpServletRequest request,
			@RequestParam(name = "apiId", required = false, defaultValue = "") String apiId) throws Exception {
		
		String sqlExceptSelect = " from " + DbapiSql.TABLE_NAME + "  a, "+Sql.TABLE_NAME+" b WHERE a.sql_id=b.id and a.api_id='" + apiId + "' ";
		sqlExceptSelect += "  ORDER BY a.sort asc ";
		List<Sql> list=Sql.dao.find("select b.name,b.identifier,b.exec,b.content  " + sqlExceptSelect);
		List<DbapiArgument> arguments=new LinkedList<DbapiArgument>();
		JSONObject content;
		DbapiArgument argument;
		for(Sql sql:list) {
			content = JSONObject.parseObject(sql.getContent());
			if(content!=null && !content.isEmpty()) {
				argument=new DbapiArgument();
				argument.setIdentifier(sql.getIdentifier());
				argument.setName(sql.getName());
				argument.setParams(content.getJSONArray("params"));
				arguments.add(argument);
			}
		}
		return R.ok(arguments);
	}

	@Operation(summary = "保存Dbapi请求参数")
	@Parameters({ @Parameter(name = "reqArguments", description = "Dbapi 请求参数对象", required = true) })
	@Tx
	@RequestMapping(value = "/req_arguments/save", method = RequestMethod.POST)
	public R<DbapiReqArguments> saveDbapiReqArguments(HttpServletRequest request,
			@RequestBody DbapiReqArguments reqArguments) {
		try {
			if (StrKit.notBlank(reqArguments.getId())) {
				reqArguments.setUpdateUserId(SecurityUtils.getUserId());
				reqArguments.setUpdateTime(new Date(System.currentTimeMillis()));
				if (reqArguments.update()) {
					return R.ok(reqArguments);
				} else {
					return R.fail("更新失败！");
				}
			} else {
				reqArguments.setId(UuidUtil.getUUID());
				reqArguments.setCreateUserId(SecurityUtils.getUserId());
				reqArguments.setCreateTime(new Date(System.currentTimeMillis()));
				if (reqArguments.save()) {
					return R.ok(reqArguments);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}

	@Operation(summary = "删除Dbapi请求参数对象")
	@Parameters({ @Parameter(name = "ids", description = "Dbapi 请求参数对象 id集合", required = true) })
	@DeleteMapping("/req_arguments/{ids}")
	@Tx(value="micro_dbapi")
	public R<String> deleteDbapiReqArguments(@PathVariable("ids") String ids) {
		String[] arr=ids.split(",");
		if(ids==null || ids.length()<=0) {
			return R.fail("请选择需要删除的参数.");
		}
		for(String id:arr) {
			DbapiReqArguments.dao.deleteById(id);
		}
		return R.ok();
	}

	@Operation(summary = "获取Dbapi SQl列表")
	@Parameters({ @Parameter(name = "apiId", description = "DbapiSql对象 Id", required = false) })
	@GetMapping(value = { "/sql/list" }, produces = "application/json; charset=utf-8")
	public R<List<DbapiSql>> getDbapiSqls(HttpServletRequest request,
			@RequestParam(name = "apiId", required = false, defaultValue = "") String apiId) throws Exception {
		String sqlExceptSelect = " from " + DbapiSql.TABLE_NAME + "  a, "+Sql.TABLE_NAME+" b WHERE a.sql_id=b.id and a.api_id='" + apiId + "' ";
		sqlExceptSelect += "  ORDER BY a.sort asc ";
		return R.ok(DbapiSql.dao.find("select a.*,b.category_id as categoryId,b.name,b.identifier,b.exec " + sqlExceptSelect));
	}
	
	@Operation(summary = "保存Dbapi Sql对象")
	@Parameters({ @Parameter(name = "sql", description = "Dbapi Sql对象", required = true) })
	@Tx
	@RequestMapping(value = "/sql/save", method = RequestMethod.POST)
	public R<DbapiSql> saveDbapiSql(HttpServletRequest request, @RequestBody DbapiSql sql) {
		try {
			if (StrKit.notBlank(sql.getId())) {
				sql.setUpdateUserId(SecurityUtils.getUserId());
				sql.setUpdateTime(new Date(System.currentTimeMillis()));
				if (sql.update()) {
					return R.ok(sql);
				} else {
					return R.fail("更新失败！");
				}
			} else {
				sql.setId(UuidUtil.getUUID());
				sql.setCreateUserId(SecurityUtils.getUserId());
				sql.setCreateTime(new Date(System.currentTimeMillis()));
				if (sql.save()) {
					return R.ok(sql);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}

	@Operation(summary = "删除Dbapi Sql对象")
	@Parameters({ @Parameter(name = "ids", description = "Dbapi Sql对象 id集合", required = true) })
	@DeleteMapping("/sql/{ids}")
	@Tx(value="micro_dbapi")
	public R<String> deleteDbapiSql(@PathVariable("ids") String ids) {
		String[] arr=ids.split(",");
		if(ids==null || ids.length()<=0) {
			return R.fail("请选择需要删除的Sql.");
		}
		for(String id:arr) {
			DbapiSql.dao.deleteById(id);
		}
		return R.ok();
	}

}
